﻿using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reactive.Linq;
using System.Windows.Data;
using ControlLibrary.Enum;
using ControlLibrary.Models;

namespace ControlLibrary.Controls;

public static class MessageExtensions
{
    /// <summary>
    ///     默认提示信息（无图标效果）
    /// </summary>
    /// <param name="queue">this</param>
    /// <param name="message">提示信息</param>
    /// <param name="time">停留时间 秒</param>
    public static void Default(this MessageHostQueue queue, string message, double time = 3)
    {
        queue.Enqueue(message, MessageType.Default, time);
    }


    /// <summary>
    ///     成功信息提示
    /// </summary>
    /// <param name="queue">this</param>
    /// <param name="message">提示信息</param>
    /// <param name="time">停留时间 秒</param>
    public static void Success(this MessageHostQueue queue, string message, double time = 3)
    {
        queue.Enqueue(message, MessageType.Success, time);
    }


    /// <summary>
    ///     警告信息提示
    /// </summary>
    /// <param name="queue">this</param>
    /// <param name="message">提示信息</param>
    /// <param name="time">停留时间 秒</param>
    public static void Warning(this MessageHostQueue queue, string message, double time = 3)
    {
        queue.Enqueue(message, MessageType.Warning, time);
    }


    /// <summary>
    ///     错误信息提示
    /// </summary>
    /// <param name="queue">this</param>
    /// <param name="message">提示信息</param>
    /// <param name="time">停留时间 秒</param>
    public static void Error(this MessageHostQueue queue, string message, double time = 3)
    {
        queue.Enqueue(message, MessageType.Error, time);
    }
}

public class MessageHostQueue
{
    // 定义一个锁对象，用于同步Items集合
    private readonly object _lockObj = new();


    // 构造函数，启用Items集合的同步

    public MessageHostQueue()
    {
        BindingOperations.EnableCollectionSynchronization(Items, _lockObj);
        // 使用Rx.NET的Observable.Interval创建一个定时Observable
        // 每隔1秒触发一次事件
        Observable
            .Interval(TimeSpan.FromSeconds(1))
            // 确保在同步上下文中执行，避免并发问题
            .Synchronize()
            // 使用Where操作符进行条件过滤
            // 只在Items集合中有元素时才继续处理
            .Where(_ =>
            {
                // 使用锁机制确保线程安全
                // 检查Items集合中是否有元素
                lock (_lockObj)
                {
                    return Items.Count > 0;
                }
            })
            // 订阅Observable，每当条件满足时执行RemoveExpiredMessages方法
            .Subscribe(_ => RemoveExpiredMessages());
    }

    // 定义一个内部ObservableCollection<MessageItem>类型的Items属性
    internal ObservableCollection<MessageItem> Items { get; } = [];

    /// <summary>
    ///     移除所有过期的消息
    /// </summary>
    private void RemoveExpiredMessages()
    {
        // 使用锁确保线程安全
        lock (_lockObj)
        {
            // 获取当前时间
            var date = DateTime.Now;
            // 筛选出所有已过期的消息
            var data = Items.Where(a => a.ExpiryTime < date).ToArray();
            // 遍历并移除所有过期的消息
            foreach (var item in data)
            {
                Items.Remove(item);
            }
        }
    }


    // 定义一个内部方法，用于将消息添加到队列中
    internal void Enqueue(string content, MessageType type, double duration = 3)
    {
        // 如果duration小于3，则将其设置为3
        if (duration < 3) duration = 3;

        // 创建一个新的MessageItem对象
        var item = new MessageItem(type, content, DateTime.Now.AddSeconds(duration));
        // 使用锁对象同步Items集合
        lock (_lockObj)
        {
            Items.Add(item);
        }

        //// 创建一个异步任务，用于延迟指定时间后移除消息
        //Task.Run(async () =>
        //{
        //    try
        //    {
        //        // 延迟指定时间
        //        await Task.Delay(TimeSpan.FromSeconds(duration));
        //        // 移除消息
        //        lock (_lockObj)
        //        {
        //            Items.Remove(item);
        //        }
        //    }
        //    catch (TaskCanceledException)
        //    {
        //        /* 正常取消 */
        //    }
        //});
    }
}